package com.vdg.ui.view;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

/**
 * This is a View class that wraps Android {@link Movie} object and displays it.
 * You can set GIF as a Movie object or as a resource id from XML or by calling
 * {@link #setMovie(Movie)} or {@link #setMovieResource(int)}.
 * <p>
 * You can pause and resume GIF animation by calling {@link #setPaused(boolean)}.
 * <p>
 * The animation is drawn in the center inside of the measured view bounds.
 * 
 * @author Sergey Bakhtiarov
 */

@SuppressLint("Instantiatable")
public class BackgroundLayout extends RelativeLayout {
	private static final int DEFAULT_MOVIEW_DURATION = 1000;
	Movie mMovie;
	InputStream mIs = null;
	long mMoviestart;
	private volatile boolean mPaused = false;
	private boolean mIsGif;
	private int mCurrentAnimationTime = 0;

	public void setMovieTime(int time) {
		mCurrentAnimationTime = time;
		invalidate();
	}

	private void updateAnimationTime() {
		long now = android.os.SystemClock.uptimeMillis();
		if (mMoviestart == 0) {
			mMoviestart = now;
		}
		int dur = mMovie.duration();
		if (dur == 0) {
			dur = DEFAULT_MOVIEW_DURATION;
		}
		if ((int) ((now - mMoviestart) / dur) == 1) {
			// mPaused=true;
			mMoviestart = now;
		} else {
			mCurrentAnimationTime = (int) ((now - mMoviestart) % dur);
		}
	}

	public BackgroundLayout(Context context) {
		super(context);
	}

	public BackgroundLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public void setPaused(boolean paused) {
		this.mPaused = paused;

		/**
		 * Calculate new movie start time, so that it resumes from the same
		 * frame.
		 */
		if (!paused) {
			mMoviestart = android.os.SystemClock.uptimeMillis()
					- mCurrentAnimationTime;
		}
		invalidate();
	}

	public boolean isPaused() {
		return this.mPaused;
	}

	// @Override
	// public void setImageBitmap(Bitmap bm) {
	// // TODO Auto-generated method stub
	// mIsGif = false;
	// super.setImageBitmap(bm);
	// }

	public void setGifImage(String gifResource) {
		mIsGif = true;
		InputStream is = null;
		try {
			is = new BufferedInputStream(new FileInputStream(new File(
					gifResource)), 32 * 1024);
			is.mark(32 * 1024);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		mMovie = Movie.decodeStream(is);
		this.setLayoutParams(new LinearLayout.LayoutParams(mMovie.width(),
				mMovie.height()));
		this.invalidate();
	}

	private void drawMovieFrame(Canvas canvas) {
		mMovie.setTime(mCurrentAnimationTime);
		canvas.save(Canvas.MATRIX_SAVE_FLAG);
		mMovie.draw(canvas, 0, 0);
		canvas.restore();
	}

	@SuppressLint("NewApi")
	private void invalidateView() {
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
			postInvalidateOnAnimation();
		} else {
			invalidate();
		}
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// if(mIsGif)
		// {
		// }
		super.onDraw(canvas);
		if (mIsGif) {
			if (mMovie != null) {
				if (!mPaused) {
					updateAnimationTime();
					drawMovieFrame(canvas);
					invalidateView();
				} else {
					drawMovieFrame(canvas);
				}
			}
		}
	}

}
